package com.yazi.mxz.common.service.impl;

import java.util.Iterator;
import java.util.List;

import com.myframework.smhj.common.tool.DateUtil;
import com.myframework.smhj.hibernate.Searching;
import com.myframework.smhj.hibernate.Page;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.yazi.mxz.common.MyUtil;
import com.yazi.mxz.common.client.ActFactory;
import com.yazi.mxz.common.entity.ValueFactory;
import com.yazi.mxz.common.entity.beans.Member;
import com.yazi.mxz.common.entity.beans.MemberSpend;
import com.yazi.mxz.common.entity.beans.Order;
import com.yazi.mxz.common.entity.beans.OrderGoods;
import com.yazi.mxz.common.entity.beans.Store;
import com.yazi.mxz.common.entity.beans.StoreGoods;
import com.yazi.mxz.common.entity.custom.Order4Search;
import com.yazi.mxz.common.entity.enums.OrderStatus;

@Service("orderService")
public class OrderServiceImpl extends OrderServiceAddImpl {
	private static Logger log = LoggerFactory.getLogger(OrderServiceImpl.class);

	@Override
	public Page<Order> list(Order4Search order, Searching si) {
		log.debug("list：Order4Search");
		return orderDao.list(order, si);
	}

	@Override
	public int count(Order4Search order, String searchWord) {
		log.debug("count：Order4Search");
		return orderDao.count(order, searchWord);
	}

	@Override
	public OrderStatus editStatusByStore(Store store, long orderId, OrderStatus status) {
		log.debug("modifyStatusByStore: storeId={},orderCode={},status={}", 
				new Object[] { store.getStoreId(), orderId, status });
		
		Order order = orderDao.get(orderId);
		if (null == order || !order.getStore().equals(store)) {
			return null;
		}

		// 订单原来的状态
		OrderStatus oldStatus = OrderStatus.values()[order.getStatus()];
		// 是否可更新
		boolean canUpdate = false;
		// 是否需要恢复库存
		boolean needStockBack = false;

		// 恢复上一次状态,必须为null
		if (null == status) {
			// 只能恢复退货申请或者拒签状态的订单
			if (oldStatus == OrderStatus.RETURNING || oldStatus == OrderStatus.REFUSE) {
				canUpdate = true;
			}
		} else {
			switch (status) {

			case CANCEL:// 取消

				// 只能取消新订单
				if (oldStatus == OrderStatus.NEW) {
					needStockBack = true;
					canUpdate = true;
				}
				break;

			case DISPATCHING:// 配送

				// 只能配送新订单
				if (oldStatus == OrderStatus.NEW) {
					canUpdate = true;
				}
				break;

			case RECEIVE:// 店铺记为"用户已签收"

				// 只能签收配送中的订单
				if (oldStatus == OrderStatus.DISPATCHING) {
					canUpdate = true;
					// 激活自动确认收货任务
					ActFactory.actOrderSuccessJob();
				}
				break;
			case REFUSE:// 店铺记为"用户拒签收"

				// 只能拒签配送中的订单
				if (oldStatus == OrderStatus.DISPATCHING) {
					canUpdate = true;
					// 激活自动确认退货任务
					ActFactory.actOrderReturnedJob();
				}
				break;
			case RETURNED:// 店铺记为"接受退货"

				// 只能接受退货申请中的订单退货
				if (oldStatus == OrderStatus.RETURNING) {
					needStockBack = true;
					canUpdate = true;
				}
				break;
			default:
				break;
			}
		}

		if (!canUpdate) {
			return null;
		}

		updateStatus(order, status);

		// 恢复库存
		if (needStockBack) {
			backStock(order);
		}
		
		return OrderStatus.values()[order.getStatus()];
	}

	@Override
	public OrderStatus editStatusByMemberId(long memberId, String orderCode, OrderStatus status) {
		log.debug("modifyStatusByMemberId: memberId={},orderCode={},status={}", 
				new Object[] { memberId, orderCode, status });
		
		if (null == orderCode) {
			return null;
		}

		// 查找用户订单
		Order order = new Order();
		order.setOrderCode(orderCode);
		Member member = new Member();
		member.setMemberId(memberId);
		order.setMemberByMemberId(member);
		List<Order> orderList = orderDao.listByExample(order);
		if (orderList.size() != 1) {
			return null;
		}

		order = orderList.get(0);
		// 订单原来的状态
		OrderStatus oldStatus = OrderStatus.values()[order.getStatus()];
		// 是否可更新
		boolean canUpdate = false;
		// 是否需要恢复库存
		boolean needStockBack = false;

		// 恢复上一次状态,必须为null
		if (null == status) {
			// 只能对正在退货申请的订单恢复上次状态
			if (oldStatus == OrderStatus.RETURNING) {
				canUpdate = true;
			}
		} else {
			switch (status) {

			case CANCEL:// 取消

				// 只能取消新订单
				if (oldStatus == OrderStatus.NEW) {
					needStockBack = true;
					canUpdate = true;
				}
				break;

			case SUCCESS:// 用户要确认收货

				// 只能确认配送中或者已经签收的订单
				if (oldStatus == OrderStatus.DISPATCHING || oldStatus == OrderStatus.RECEIVE) {
					// 赠送积分
					member = order.getMemberByMemberId();
					member.setIntegral(member.getIntegral() + order.getIntegral());
					memberDao.merge(member);
					canUpdate = true;
					
					// 消费记录
					MemberSpend ms = new MemberSpend();
					ValueFactory.validate(ms);
					ms.setIsChecked(true);
					ms.setMember(member);
					ms.setSerialCode(order.getSerialCode());
					ms.setSpend(order.getRealCost());
					ms.setSpendTime(order.getStatusTime());
					memberSpendDao.persist(ms);
					
				}
				break;
				
			case RETURNING:// 申请退货

				// 只能对配送中或者已经签收的订单进行退货申请
				if (oldStatus == OrderStatus.DISPATCHING || oldStatus == OrderStatus.RECEIVE) {
					canUpdate = true;
				}
				break;
			default:
				break;
			}
		}

		if (!canUpdate) {
			return null;
		}

		updateStatus(order, status);

		// 恢复库存
		if (needStockBack) {
			backStock(order);
		}
		
		return OrderStatus.values()[order.getStatus()];
	}

	@Override
	public Order oneNextSuccess() {
		Order order = orderDao.oneNextSuccess();
		log.debug("oneNextSuccess：{}",
				null == order ? "None" : DateUtil.getDateTimeStr(order.getStatusTime()));
		return order;
	}

	@Override
	public Order oneNextReturned() {
		Order order = orderDao.oneNextReturned();
		log.debug("oneNextReturned：{}",
				null == order ? "None" : DateUtil.getDateTimeStr(order.getStatusTime()));
		return order;
	}

	@Override
	public void editToReturned(long orderId) {
		
		Order order = orderDao.get(orderId);
		if (null == order) {
			log.debug("modifyToReturned：orderId={},要自动确认退货的订单不存在", orderId);
			return;
		}
		
		// 自动确认退货的只能是拒签的订单
		if (order.getStatus() != OrderStatus.REFUSE.ordinal()) {
			log.debug("modifyToReturned：orderId={},status={}，不能自动确认退货(非拒签订单)", order.getOrderId(), order.getStatus());
			return;
		}
		
		log.debug("modifyToReturned：orderId={},statusTime={}", 
				order.getOrderId(),DateUtil.getDateTimeStr(order.getStatusTime()));
		
		updateStatus(order, OrderStatus.RETURNED);
		backStock(order);
	}

	@Override
	public void editToSuccess(long orderId) {
		
		Order order = orderDao.get(orderId);
		if (null == order) {
			log.debug("modifyToSuccess：orderId={},要自动确认收货的订单不存在", orderId);
			return;
		}
		
		// 自动确认收货的只能是已经签收的订单
		if (order.getStatus() != OrderStatus.RECEIVE.ordinal()) {
			log.debug("modifyToSuccess：orderId={},status={},不能自动确认收货(非签收订单)", 
					orderId, order.getStatus());
			return;
		}
		
		log.debug("modifyToSuccess：orderId={},statusTime={}", 
				orderId,DateUtil.getDateTimeStr(order.getStatusTime()));
		
		updateStatus(order, OrderStatus.SUCCESS);
	}

	@Override
	public boolean removeByStore(Store store, long orderId) {
		log.debug("removeByStore: storeId={},orderId={}", store.getStoreId(), orderId);
		
		Order order = orderDao.get(orderId);
		if (null == order || !order.getStore().equals(store)) {
			return false;
		}
		
		OrderStatus orderStatus = OrderStatus.values()[order.getStatus()];
		boolean isSuccess = false;

		/**
		 *  只能删除已经取消的、交易成功的、拒签的、退货成功的订单
		 */
		switch (orderStatus) {
		case CANCEL:
		case SUCCESS:
		case REFUSE:
		case RETURNED:
			// 店铺要删除的订单,用户那边已经"删除"了,则直接删除订单记录
			if (order.getIsMemberDel()) {
				//orderGoodsDao.deleteByOrderId(order.getOrderId());
				//orderDao.delete(order);
				isSuccess = true;
			} else {
				order.setIsStoreDel(true);
				orderDao.merge(order);
				isSuccess = true;
			}
			break;
		default:
			break;
		}

		return isSuccess;
	}

	@Override
	public boolean removeByMemberId(long memberId, String orderCode) {
		log.debug("removeByMemberId: memberId={},orderCode={}", memberId, orderCode);
		
		if (null == orderCode) {
			return false;
		}

		// 查找用户订单
		Order order = new Order();
		order.setOrderCode(orderCode);
		Member member = new Member();
		member.setMemberId(memberId);
		order.setMemberByMemberId(member);
		List<Order> orderList = orderDao.listByExample(order);
		if (orderList.size() != 1) {
			return false;
		}

		order = orderList.get(0);
		OrderStatus orderStatus = OrderStatus.values()[order.getStatus()];
		boolean isSuccess = false;

		/**
		 *  只能删除已经取消的、交易成功的、拒签的、退货成功的订单
		 */
		switch (orderStatus) {
		case CANCEL:
		case SUCCESS:
		case REFUSE:
		case RETURNED:
			// 用户要删除的订单,店铺那边已经"删除"了,则直接删除订单记录
			if (order.getIsStoreDel()) {
				//orderGoodsDao.deleteByOrderId(order.getOrderId());
				//orderDao.delete(order);
				isSuccess = true;
			} else {
				order.setIsMemberDel(true);
				orderDao.merge(order);
				isSuccess = true;
			}
			break;
		default:
			break;
		}

		return isSuccess;
	}
	
	private void updateStatus(Order order, OrderStatus status) {
		// 更新状态
		Integer curStatus = order.getStatus();
		if (null == status) {
			order.setStatus((int) order.getPrevStatus());
			order.setPrevStatus(curStatus);
		} else {
			order.setStatus(status.ordinal());
			order.setPrevStatus(curStatus);
		}
		order.setStatusTime(DateUtil.getTimeStamp());
		orderDao.merge(order);

	}


	/**
	 * 恢复库存
	 * @param order
	 */
	private void backStock(Order order) {
		
		// 恢复库存的条件：
		// 订单没有执行过库存恢复，且处于取消、或者确认退货状态
		OrderStatus status = OrderStatus.values()[order.getStatus()];
		
		if (order.getIsStockBack()
				|| (status != OrderStatus.CANCEL && status != OrderStatus.RETURNED)) {
			log.debug("订单不能恢复库存：orderId={}", order.getOrderId());
			return;
		}
		
		
		Iterator<OrderGoods> it = order.getOrderGoodses().iterator();
		OrderGoods og;
		StoreGoods sg;
		
		while (it.hasNext()) {
			
			og = it.next();
			sg = storeGoodsDao.get(og.getStoreGoodsId());
			if (null == sg) {
				continue;
			}
			
			if (null == og.getBuyUnit()) {
				sg.setStock(MyUtil.numRoundDown(sg.getStock() + og.getBuyCount(), 2).floatValue());
				sg.setStockConvert(sg.getStock());
			} else {
				sg.setStock(MyUtil.numRoundDown(sg.getStock() + og.getRealCount(), 2).floatValue());
				sg.setStockConvert(MyUtil.numRoundDown(sg.getStockConvert() + og.getBuyCount(), 0).floatValue());// 取整
			}
			
			storeGoodsDao.merge(sg);
		}
		
		order.setIsStockBack(true);
		orderDao.merge(order);
	}

}
